﻿using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Brushes;
using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Geometry;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Input.Spatial;
using 纸片人.PageViews;

namespace 纸片人
{
    public class PictureFilter
    {
        #region 非线性滤波效果
        /// <summary>
        /// 非线性滤波效果
        /// </summary>
        /// <param name="source">源颜色数组</param>
        /// <param name="width">图像宽度</param>
        /// <param name="height">图像高度</param>
        /// <param name="r">滤波半径</param>
        /// <returns>效果颜色数组</returns>
        public static Color[] NonLinearEffect(Color[] source, int width, int height, int r)
        {

            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {

                    NonLinearFiltterPool(sx, sy, ex, ey, source, r, width, height, target);
                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());



            return target;
        }

        static void NonLinearFiltterPool(int sx, int sy, int ex, int ey, Color[] source, int r, int width, int height, Color[] target)
        {

            List<Color> mc = new List<Color>();

            bool isOne = true;

            for (int x = sx; x < ex; x++)
            {
                isOne = true;
                for (int y = sy; y < ey; y++)
                {
                    if (isOne)
                    {
                        initialzationMatricColor(source, x, y, r, mc, width, height, target);
                        isOne = false;
                    }
                    else
                    {
                        Mc(source, x, y, r, mc, width, height, target);
                    }
                }
            }





        }

        private static void Mc(Color[] cs, int x, int y, int r, List<Color> minColor, int width, int height, Color[] target)
        {
            int sx = x - r;

            int ex = x + r;
            int ey = y + r;

            if (sx < 0)
                sx = 0;

            if (ex > width - 1) ex = width - 2;
            if (ey > height - 1) ey = height - 2;

            minColor.RemoveAt(0);

            Color minC = Color.FromArgb(255, 255, 255, 255);

            for (int i = sx; i <= ex; i++)
            {
                Color temp = cs[i + ey * width];
                if (temp.R < minC.R)
                {
                    minC.R = temp.R;
                }

                if (temp.G < minC.G)
                {
                    minC.G = temp.G;
                }

                if (temp.B < minC.B)
                {
                    minC.B = temp.B;
                }
            }

            minColor.Add(minC);


            Color m = Color.FromArgb(255, 255, 255, 255);

            byte rr = 255, gg = 255, bb = 255;

            foreach (var temp in minColor)
            {
                if (temp.R < rr)
                {
                    rr = temp.R;
                }

                if (temp.G < gg)
                {
                    gg = temp.G;
                }

                if (temp.B < bb)
                {
                    bb = temp.B;
                }
            }


            m.R = rr;
            m.G = gg;
            m.B = bb;


            target[x + y * width] = m;
        }

        static void initialzationMatricColor(Color[] cs, int x, int y, int r, List<Color> mc, int width, int height, Color[] target)
        {


            int sx = x - r;
            int sy = y - r;
            int ex = x + r;
            int ey = y + r;

            if (sx < 0)
                sx = 0;

            if (ex > width - 1) ex = width - 2;
            if (ey > height - 1) ey = height - 2;


            mc.Clear();

            for (int cy = sy; cy <= ey; cy++)
            {
                Color minC = Color.FromArgb(255, 255, 255, 255);

                if (cy < 0)
                {
                    mc.Add(minC);
                    continue;
                }

                for (int cx = sx; cx <= ex; cx++)
                {

                    Color temp = cs[cx + cy * width];

                    if (temp.R < minC.R)
                    {
                        minC.R = temp.R;
                    }

                    if (temp.G < minC.G)
                    {
                        minC.G = temp.G;
                    }

                    if (temp.B < minC.B)
                    {
                        minC.B = temp.B;
                    }

                }
                mc.Add(minC);

            }
            Color m = Color.FromArgb(255, 255, 255, 255);

            byte rr = 255, gg = 255, bb = 255;

            foreach (var temp in mc)
            {
                if (temp.R < rr)
                {
                    rr = temp.R;
                }

                if (temp.G < gg)
                {
                    gg = temp.G;
                }

                if (temp.B < bb)
                {
                    bb = temp.B;
                }
            }
            m.R = rr;
            m.G = gg;
            m.B = bb;
            target[x + y * width] = m;
        }

        #endregion

        #region 图像发黄效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] YellowingEffect(Color[] source, int width, int height)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            Color c = source[x + y * width];

                            double r = c.R;
                            double g = c.G;
                            double b = c.B;

                            int nr = (int)((25756 * r) + (50397 * g) + (12386 * b)) >> 16;
                            int ng = (int)((22872 * r) + (44958 * g) + (11010 * b)) >> 16;
                            int nb = (int)((17826 * r) + (34996 * g) + (8585 * b)) >> 16;

                            if (nr < 0)
                                nr = 0;
                            if (nr > 255)
                                nr = 255;
                            if (ng < 0)
                                ng = 0;
                            if (ng > 255)
                                ng = 255;
                            if (nb < 0)
                                nb = 0;
                            if (nb > 255)
                                nb = 255;

                            Color dc = Color.FromArgb(255, (byte)nr, (byte)ng, (byte)nb);

                            target[x + y * width] = dc;

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像灰度效果

        private static void GrayEffect(int sx, int ex, Color[] source, Color[] target, bool weight = true)
        {



        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] GrayEffect(Color[] source, int width, int height, bool weight = true)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            int len = source.Length;
            int part = len / 12;
            Color[] target = new Color[source.Length];



            int sx = 0;
            int ex = part;
            for (int i = 0; i < 12; i++)
            {
                if (i == 11)
                {
                    ex = len - 1;
                }


                int ssx = sx;
                int eex = ex;
                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {

                    for (int x = ssx; x < eex; x++)
                    {

                        Color c = source[x];
                        int gray = 0;

                        if (weight)
                        {
                            gray = (c.B * 299 + c.R * 587 + c.G * 114) / 1000;

                        }
                        else
                        {
                            gray = (c.B + c.R + c.G) / 3;
                        }

                        target[x] = Color.FromArgb(255, (byte)gray, (byte)gray, (byte)gray);


                    }
                }



                    ));

                sx += part;
                ex += part;

            }


            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像黑白效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] BlackOrWhiteEffect(Color[] source, int width, int height, bool weight = true)
        {


            Color[] target = new Color[source.Length];
            List<IAsyncAction> list = MultiThreading(width, height, (sx, sy, ex, ey) =>
            {


                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        Color c = source[x + y * width];
                        int gray = 0;

                        if (weight)
                        {
                            gray = (c.B * 299 + c.R * 587 + c.G * 114) / 1000;

                        }
                        else
                        {
                            gray = (c.B + c.R + c.G) / 3;
                        }


                        if (gray > 128)
                        {
                            gray = 255;
                        }
                        else
                        {
                            gray = 0;
                        }

                        target[x + y * width] = Color.FromArgb(255, (byte)gray, (byte)gray, (byte)gray);

                    }
                }


            });


            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像扭曲效果

        /// <summary>
        /// 图像扭曲效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] DistortionEffect(Color[] source, int width, int height, double angle, double r, Point center, bool diretion = true)
        {


            Color[] target = new Color[source.Length];

            double ang = 0;
            if (diretion)
            {
                ang = (double)(angle / 180) * Math.PI;
            }
            else
            {
                ang = (double)(-angle / 180) * Math.PI;

            }

            double radius2 = r * r;

            List<IAsyncAction> list = MultiThreading(width, height, (sx, sy, ex, ey) =>
            {



                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {

                        var centerPos = center.ToVector2();
                        var currentPos = new Vector2(x, y);

                        var disPos = Vector2.Subtract(currentPos, centerPos);

                        var distance = Vector2.Distance(centerPos, currentPos);
                        if (r > distance)
                        {
                            //当前弧度
                            var currentRadin = Math.Atan2(disPos.Y, disPos.X);
                            //需要旋转的弧度
                            var rotateRadin = ang * (r - distance) / r;
                            //旋转后的弧度
                            var targetRadin = currentRadin + rotateRadin;
                            //旋转后的位置
                            var tx = center.X + Math.Cos(targetRadin) * distance;
                            var ty = center.Y + Math.Sin(targetRadin) * distance;

                            tx = Math.Min(Math.Max(0, tx), width - 1);
                            ty = Math.Min(Math.Max(0, ty), height - 1);
                            target[x + y * width] = Function.BiLinear(tx, ty, source, width, height);
                        }
                        else
                        {
                            target[x + y * width] = source[x + y * width];
                        }


                    }
                }


            });


            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 极坐标到平面效果

        /// <summary>
        /// 极坐标到平面效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] PolarPlaneCoorrEffect(Color[] source, int width, int height)
        {



            Color[] target = new Color[source.Length];
            double r = height / 2;
            double m = width / height;

            Point center = new Point(width / 2, height / 2);

            List<IAsyncAction> list = MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {

                        double ry = y * r / height;
                        double rx = ry * m;

                        double theta = x * 2 * Math.PI / width;

                        double dx = center.X + rx * Math.Cos(theta);
                        double dy = center.Y - ry * Math.Sin(theta);

                        target[x + y * width] = Function.BiLinear(dx, dy, source, width, height);
                    }
                }


            });


            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion


        #region 平面到极坐标效果

        /// <summary>
        /// 平面到极坐标效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] CoorPlanePolarEffect(Color[] source, int width, int height)
        {


            Color[] target = new Color[source.Length];
            double r = height / 2;


            Point center = new Point(width / 2, height / 2);

            List<IAsyncAction> list = MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {

                        double a = center.Y - y;
                        double b = x - center.X;


                        double theta = Math.Atan2(a, b * 2);

                        if (a <= 0)
                            theta = theta + 2 * Math.PI;
                        double r1 = a / Math.Sin(theta);
                        double dx = theta * width / (2 * Math.PI);
                        double dy = r1 * height / r; ;

                        target[x + y * width] = Function.BiLinear(dx, dy, source, width, height);
                    }
                }


            });

            //var src_width = width;
            //var src_height = height;

            //var dstSize =new  Vector2(src_width*2,src_height*2);
            //var center = new Vector2(width , height);
            //var target = new Color[(int)(dstSize.X*dstSize.Y)];
            //var scale_r = 2 * src_height / src_width;
            //var  scale_theta = src_width / (Math.PI * 2);

            //List<IAsyncAction> list = MultiThreading((int)dstSize.X,(int) dstSize.Y, (sx, sy, ex, ey) =>
            //{

            //    for (int x = sx; x < ex; x++)
            //    {
            //        for (int y = sy; y < ey; y++)
            //        {

            //            var distance = Vector2.Distance(new Vector2(x, y),center );

            //            if(distance < width)
            //            {

            //                var rec_y = distance * scale_r;
            //                if (rec_y < 0)
            //                {
            //                    rec_y = 0;


            //                }
            //                if (rec_y > dstSize.X / 2)
            //                {
            //                    rec_y = dstSize.X / 2;

            //                }

            //                var lien_theta = Math.Atan2(x - center.Y, y - center.X);

            //                if (lien_theta < 0)
            //                {
            //                    lien_theta += Math.PI * 2;
            //                }

            //                var rec_x = lien_theta * scale_theta;
            //                target[x + y * width] = Function.BiLinear(rec_y, rec_x, source, width, height);

            //            }



            //        }
            //    }


            //});

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 扇形图形效果



        /// <summary>
        /// 扇形图形效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="innerCircleRadius">内圆直径大小,默认是0,最大是10,为宽度的百分比</param>
        /// <returns></returns>
        public static Color[] SectorGraphicsEffect(Color[] source, int width, int height, float innerCircleRadius = 0)
        {

            innerCircleRadius = (innerCircleRadius / 10f) * width;

            Color[] target = new Color[source.Length];

            Point center = new Point(width / 2, height);

            double angle = 0; //根据中心点控制旋转角度

            double high = (width - innerCircleRadius * 2) / 2;
            double pi = Math.PI;



            List<IAsyncAction> list = MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        double dx = x - center.X;
                        double dy = y - center.Y;

                        double theata = Math.Atan2(-dy, -dx) + angle;

                        double r = Math.Sqrt(dy * dy + dx * dx);
                        theata = theata % (2f * pi);

                        double nx = width * theata / (pi + 0.00001);
                        double ny = height * (1 - (r - innerCircleRadius) / (high + 0.00001));

                        //if (nx < 0) continue;
                        //if (nx >= width - 1) continue;
                        //if (ny >= height - 1) continue;
                        //if (ny < 0) continue;

                        target[x + y * width] = Function.BiLinear(nx, ny, source, width, height);

                    }
                }


            });


            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion


        #region 图像素描效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] PencilEffect(Color[] source, int width, int height, int edgeIntensity)
        {
            Color[] target = new Color[source.Length];
            int[] lightMap = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 104, 105, 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 128, 129, 130, 132, 133, 134, 135, 136, 137, 138, 140, 141, 142, 143, 144, 145, 146, 147, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 164, 165, 166, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 212, 213, 214, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 225, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233, 233, 234, 235, 235, 236, 237, 238, 238, 239, 240, 240, 241, 242, 242, 243, 243, 244, 245, 245, 246, 246, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 253, 254, 254, 255, 255 };

            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        Color color = Color.FromArgb(255, 255, 255, 255);
                        if (x == 0 || x == width - 1 || y == 0 || y == height - 1)
                        {
                            int index = x + y * width;
                            target[index] = color;
                        }

                        else
                        {
                            int r0, r1, r2, r3, r4, r5, r6, r7, r8;
                            int g1, g2, g3, g4, g5, g6, g7, g8, g0;
                            int b1, b2, b3, b4, b5, b6, b7, b8, b0;
                            double vR, vG, vB;

                            int lx = x - 1;
                            int rx = x + 1;
                            int t = y - 1;
                            int b = y + 1;
                            int gray = 0;

                            //左上
                            int index = lx + t * width;
                            color = source[index];
                            r1 = color.R;
                            g1 = color.G;
                            b1 = color.B;
                            //正上
                            index = x + t * width;
                            color = source[index];
                            r2 = color.R;
                            g2 = color.G;
                            b2 = color.B;
                            //右上
                            index = rx + t * width;
                            color = source[index];
                            r3 = color.R;
                            g3 = color.G;
                            b3 = color.B;
                            //左
                            index = lx + y * width;
                            color = source[index];
                            r4 = color.R;
                            g4 = color.G;
                            b4 = color.B;
                            //右
                            index = rx + y * width;
                            color = source[index];
                            r5 = color.R;
                            g5 = color.G;
                            b5 = color.B;
                            //左下
                            index = lx + b * width;
                            color = source[index];
                            r6 = color.R;
                            g6 = color.G;
                            b6 = color.B;
                            //正下
                            index = x + b * width;
                            color = source[index];
                            r7 = color.R;
                            g7 = color.G;
                            b7 = color.B;
                            // 右下 
                            index = rx + b * width;
                            color = source[index];
                            r8 = color.R;
                            g8 = color.G;
                            b8 = color.B;
                            //中心点
                            index = x + y * width;
                            color = source[index];
                            r0 = color.R;
                            g0 = color.G;
                            b0 = color.B;
                            //使用模板
                            vR = (double)(Math.Abs(r1 + 2 * r4 + r6 - r3 - 2 * r5 - r8) + Math.Abs(r1 + 2 * r2 + r3 - r6 - 2 * r7 - r8));
                            vG = (double)(Math.Abs(g1 + 2 * g4 + g6 - g3 - 2 * g5 - g8) + Math.Abs(g1 + 2 * g2 + g3 - g6 - 2 * g7 - g8));
                            vB = (double)(Math.Abs(b1 + 2 * b4 + b6 - b3 - 2 * b5 - b8) + Math.Abs(b1 + 2 * b2 + b3 - b6 - 2 * b7 - b8));
                            vB = Math.Min(255, Math.Max(0, vB));
                            vG = Math.Min(255, Math.Max(0, vG));
                            vR = Math.Min(255, Math.Max(0, vR));
                            gray = lightMap[255 - (int)(vB + vG + vR) / 3];
                            gray = Math.Min(255, gray + edgeIntensity);
                            gray = Math.Max(0, gray);
                            target[x + y * width] = Color.FromArgb(255, (byte)gray, (byte)gray, (byte)gray);

                        }



                    }
                }
            }).Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion


        #region 图像油画效果

        /// <summary>
        ///  油画效果
        /// </summary>
        /// <param name="source">图片源颜色数组</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <param name="radius">半径</param>
        /// <param name="smooth">平滑</param>
        /// <returns></returns>
        public static Color[] OilpaintPaintEffect(Color[] source, int width, int height, int radius, int smooth)
        {
            //图像颜色数组
            Color[] target = new Color[source.Length];
            //平滑大小
            smooth = smooth < 1 ? 1 : smooth;
            //范围
            radius = radius > Math.Min(width, height) / 2 ? Math.Min(width, height) / 2 - 1 : radius;

            int[] graySum = new int[smooth];
            int[] redSum = new int[smooth];
            int[] greenSum = new int[smooth];
            int[] blueSum = new int[smooth];
            //原图灰度平滑比例
            int[] graySumSrc = new int[smooth];
            //原图红色总和
            int[] redSumSrc = new int[smooth];
            //原图绿色总和
            int[] greenSumSrc = new int[smooth];
            //原图蓝色总和
            int[] blueSumSrc = new int[smooth];
            int r, g, b;
            bool frist = true;
            for (int j = 0; j < height; j++)
            {
                //第一个像素
                if (frist)
                {
                    //循环指定的范围
                    for (int y = -radius; y <= radius; y++)
                    {
                        for (int x = -radius; x <= radius; x++)
                        {
                            //采样索引
                            var posIndex = Math.Abs(x) + Math.Abs(y) * width;
                            Color col = source[posIndex];
                            int gray = (col.B + col.G + col.R) / 3;
                            //平滑索引
                            var sommthIndex = gray * smooth >> 8;
                            //
                            graySumSrc[sommthIndex]++;
                            //三个颜色通道的总和
                            blueSumSrc[sommthIndex] += col.B;
                            greenSumSrc[sommthIndex] += col.G;
                            redSumSrc[sommthIndex] += col.R;
                        }
                    }
                    Array.Copy(graySumSrc, graySum, smooth);
                    Array.Copy(blueSumSrc, blueSum, smooth);
                    Array.Copy(greenSumSrc, greenSum, smooth);
                    Array.Copy(redSumSrc, redSum, smooth);
                    int max = 0;
                    int maxindex = 0;
                    //循环记录灰度比例的列表，计算颜色,找出最大值和索引
                    for (int i = 0; i < smooth; i++)
                    {
                        if (max < graySum[i])
                        {
                            max = graySum[i];
                            maxindex = i;
                        }
                    }
                    Color c = new Color();
                    c.B = (byte)(blueSum[maxindex] / max);
                    c.G = (byte)(greenSum[maxindex] / max);
                    c.R = (byte)(redSum[maxindex] / max);
                    target[0] = c;
                    frist = false;
                }
                else
                {
                    for (int m = -radius; m <= radius; m++)
                    {
                        var pos = Math.Abs(m) + Math.Abs(j - radius - 1) * width;
                        Color srcColor = source[pos];
                        b = srcColor.B;
                        g = srcColor.G;
                        r = srcColor.R;
                        int gray = (b + g + r) / 3;
                        var sommthIndex = gray * smooth >> 8;
                        graySumSrc[sommthIndex]--;
                        blueSumSrc[sommthIndex] -= b;
                        greenSumSrc[sommthIndex] -= g;
                        redSumSrc[sommthIndex] -= r;

                        pos = Math.Abs(m) + Math.Abs(j + radius) % height * width;
                        srcColor = source[pos];
                        b = srcColor.B;
                        g = srcColor.G;
                        r = srcColor.R;
                        gray = (b + g + r) / 3;
                        sommthIndex = gray * smooth >> 8;
                        graySumSrc[sommthIndex]++;
                        blueSumSrc[sommthIndex] += b;
                        greenSumSrc[sommthIndex] += g;
                        redSumSrc[sommthIndex] += r;
                    }
                    Array.Copy(graySumSrc, graySum, smooth);
                    Array.Copy(blueSumSrc, blueSum, smooth);
                    Array.Copy(greenSumSrc, greenSum, smooth);
                    Array.Copy(redSumSrc, redSum, smooth);
                }
                for (int i = 1; i < width; i++)
                {
                    for (int m = -radius; m <= radius; m++)
                    {
                        var pos = Math.Abs(i - radius - 1) + Math.Abs(j + m) % height * width;
                        Color srcColor = source[pos];
                        b = srcColor.B;
                        g = srcColor.G;
                        r = srcColor.R;
                        int gray = (b + g + r) / 3;
                        var sommthIndex = gray * smooth >> 8;
                        graySum[sommthIndex]--;
                        blueSum[sommthIndex] -= b;
                        greenSum[sommthIndex] -= g;
                        redSum[sommthIndex] -= r;

                        pos = Math.Abs(i + radius) % width + Math.Abs(j + m) % height * width;
                        srcColor = source[pos];
                        b = srcColor.B;
                        g = srcColor.G;
                        r = srcColor.R;
                        gray = (b + g + r) / 3;
                        sommthIndex = gray * smooth >> 8;
                        graySum[sommthIndex]++;
                        blueSum[sommthIndex] += b;
                        greenSum[sommthIndex] += g;
                        redSum[sommthIndex] += r;
                    }
                    int max = 0;
                    int maxindex = 0;
                    for (int k = 0; k < smooth; k++)
                    {
                        if (max < graySum[k])
                        {
                            max = graySum[k];
                            maxindex = k;
                        }
                    }
                    var targetPos = i + j * width;
                    Color sc = source[targetPos];
                    sc.B = (byte)(blueSum[maxindex] / max);
                    sc.G = (byte)(greenSum[maxindex] / max);
                    sc.R = (byte)(redSum[maxindex] / max);

                    target[targetPos] = sc;

                }
            }



            return target;
        }
        #endregion


        #region 图像油画效果

        /// <summary>
        ///  油画效果
        /// </summary>
        /// <param name="source">图片源颜色数组</param>
        /// <param name="width">图片宽度</param>
        /// <param name="height">图片高度</param>
        /// <param name="radius">半径</param>
        /// <param name="smooth">平滑</param>
        /// <returns></returns>
        public static Color[] OilpaintPaintEffect3(Color[] source, int width, int height, int radius, int smooth)
        {
            //图像颜色数组
            Color[] target = new Color[source.Length];
            //平滑大小
            smooth = smooth < 1 ? 1 : smooth;
            //范围
            radius = radius > Math.Min(width, height) / 2 ? Math.Min(width, height) / 2 - 1 : radius;




            for (int cx = 0; cx < width; cx++)
            {
                for (int cy = 0; cy < height; cy++)
                {
                    int[] graySum = new int[smooth];
                    int[] redSum = new int[smooth];
                    int[] greenSum = new int[smooth];
                    int[] blueSum = new int[smooth];
                    //循环指定的范围
                    for (int y = -radius; y <= radius; y++)
                    {
                        for (int x = -radius; x <= radius; x++)
                        {

                            var ex = cx + x;
                            var ey = cy + y;
                            if (ex < 0 || ex >= width || ey < 0 || ey >= height)
                            {
                                continue;
                            }


                            //采样索引
                            var posIndex = ex + ey * width;
                            Color col = source[posIndex];
                            int gray = (col.B + col.G + col.R) / 3;
                            //平滑索引
                            var sommthIndex = gray * smooth >> 8;
                            Console.WriteLine(sommthIndex);
                            graySum[sommthIndex]++;
                            //三个颜色通道的总和
                            redSum[sommthIndex] += col.R;
                            greenSum[sommthIndex] += col.G;
                            blueSum[sommthIndex] += col.B;

                        }
                    }
                    int max = 0;
                    int maxindex = 0;
                    //循环记录灰度比例的列表，计算颜色,找出最大值和索引
                    for (int i = 0; i < smooth; i++)
                    {
                        if (max < graySum[i])
                        {
                            max = graySum[i];
                            maxindex = i;
                        }
                    }
                    Color c = new Color();
                    c.A = 255;
                    c.B = (byte)(blueSum[maxindex] / max);
                    c.G = (byte)(greenSum[maxindex] / max);
                    c.R = (byte)(redSum[maxindex] / max);
                    var index = cx + cy * width;
                    target[index] = c;
                }

            }

            return target;
        }
        #endregion

        #region 图像油画效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] OilpaintPaintEffect2(Color[] source, int width, int height, int radius, int smooth)
        {
            Color[] target = new Color[source.Length];

            smooth = smooth < 1 ? 1 : smooth;
            radius = radius > Math.Min(width, height) / 2 ? Math.Min(width, height) / 2 - 1 : radius;





            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {



                int[] graySum = new int[smooth];
                int[] redSum = new int[smooth];
                int[] greenSum = new int[smooth];
                int[] blueSum = new int[smooth];
                int[] graySumSrc = new int[smooth];
                int[] redSumSrc = new int[smooth];
                int[] greenSumSrc = new int[smooth];
                int[] blueSumSrc = new int[smooth];
                int r, g, b;
                int gray = 0, sommthIndex = 0, max = 0, maxindex = 0;

                bool frist = true;
                int pos = 0;

                for (int y = sy; y < ey; y++)
                {

                    if (frist)
                    {
                        for (int m = -radius; m <= radius; m++)
                        {
                            for (int n = -radius; n <= radius; n++)
                            {
                                pos = Math.Abs(n) + Math.Abs(m) * width;
                                Color col = source[pos];
                                b = col.B;
                                g = col.G;
                                r = col.R;
                                gray = (b + g + r) / 3;
                                sommthIndex = gray * smooth >> 8;
                                graySumSrc[sommthIndex]++;
                                blueSumSrc[sommthIndex] += b;
                                greenSumSrc[sommthIndex] += g;
                                redSumSrc[sommthIndex] += r;
                            }
                        }
                        Array.Copy(graySumSrc, graySum, smooth);
                        Array.Copy(blueSumSrc, blueSum, smooth);
                        Array.Copy(greenSumSrc, greenSum, smooth);
                        Array.Copy(redSumSrc, redSum, smooth);
                        max = 0;
                        maxindex = 0;
                        for (int k = 0; k < smooth; k++)
                        {
                            if (max < graySum[k])
                            {
                                max = graySum[k];
                                maxindex = k;
                            }
                        }
                        pos = y * width;
                        Color c = new Color();
                        c.B = (byte)(blueSum[maxindex] / max);
                        c.G = (byte)(greenSum[maxindex] / max);
                        c.R = (byte)(redSum[maxindex] / max);
                        target[pos] = c;
                        frist = false;
                    }
                    else
                    {
                        for (int m = -radius; m <= radius; m++)
                        {
                            pos = Math.Abs(m) + Math.Abs(y - radius - 1) * width;
                            Color srcColor = source[pos];
                            b = srcColor.B;
                            g = srcColor.G;
                            r = srcColor.R;
                            gray = (b + g + r) / 3;
                            sommthIndex = gray * smooth >> 8;
                            graySumSrc[sommthIndex]--;
                            blueSumSrc[sommthIndex] -= b;
                            greenSumSrc[sommthIndex] -= g;
                            redSumSrc[sommthIndex] -= r;

                            pos = Math.Abs(m) + Math.Abs(y + radius) % height * width;
                            srcColor = source[pos];
                            b = srcColor.B;
                            g = srcColor.G;
                            r = srcColor.R;
                            gray = (b + g + r) / 3;
                            sommthIndex = gray * smooth >> 8;
                            graySumSrc[sommthIndex]++;
                            blueSumSrc[sommthIndex] += b;
                            greenSumSrc[sommthIndex] += g;
                            redSumSrc[sommthIndex] += r;
                        }
                        Array.Copy(graySumSrc, graySum, smooth);
                        Array.Copy(blueSumSrc, blueSum, smooth);
                        Array.Copy(greenSumSrc, greenSum, smooth);
                        Array.Copy(redSumSrc, redSum, smooth);
                    }

                    for (int x = sx; x < ex; x++)
                    {



                        if (x <= 1)
                        {
                            int index = x + y * width;

                            target[index] = source[index];

                        }

                        for (int m = -radius; m <= radius; m++)
                        {
                            pos = Math.Abs(x - radius - 1) + Math.Abs(y + m) % height * width;
                            Color srcColor = source[pos];
                            b = srcColor.B;
                            g = srcColor.G;
                            r = srcColor.R;
                            gray = (b + g + r) / 3;
                            sommthIndex = gray * smooth >> 8;
                            graySum[sommthIndex]--;
                            blueSum[sommthIndex] -= b;
                            greenSum[sommthIndex] -= g;
                            redSum[sommthIndex] -= r;

                            pos = Math.Abs(x + radius) % width + Math.Abs(y + m) % height * width;
                            srcColor = source[pos];
                            b = srcColor.B;
                            g = srcColor.G;
                            r = srcColor.R;
                            gray = (b + g + r) / 3;
                            sommthIndex = gray * smooth >> 8;
                            graySum[sommthIndex]++;
                            blueSum[sommthIndex] += b;
                            greenSum[sommthIndex] += g;
                            redSum[sommthIndex] += r;
                        }
                        max = 0;
                        maxindex = 0;
                        for (int k = 0; k < smooth; k++)
                        {
                            if (max < graySum[k])
                            {
                                max = graySum[k];
                                maxindex = k;
                            }
                        }
                        pos = x + y * width;
                        Color sc = source[pos];
                        b = sc.B;

                        g = sc.G;
                        r = sc.R;
                        sc.B = (byte)(blueSum[maxindex] / max);
                        sc.G = (byte)(greenSum[maxindex] / max);
                        sc.R = (byte)(redSum[maxindex] / max);

                        target[pos] = sc;



                    }
                }
            }, 2).Select(temp => temp.AsTask()).ToArray());





            return target;
        }

        #endregion

        #region 图像反色效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] InvertEffect(Color[] source, int width, int height)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            Color c = source[x + y * width];

                            c.R = (byte)(255 - c.R);
                            c.G = (byte)(255 - c.G);
                            c.B = (byte)(255 - c.B);



                            target[x + y * width] = c;

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 照亮边缘效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] LightEdgeEffect(Color[] source, int width, int height)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            int r = 0, g = 0, b = 0;

                            Color c1 = source[x + y * width];
                            //右边
                            Color c2 = source[x + 1 + y * width];
                            //下边
                            Color c3 = source[x + (y + 1) * width];

                            int gray1 = (c1.R + c1.G + c1.B) / 3;
                            int gray2 = (c2.R + c2.G + c2.B) / 3;
                            int gray3 = (c3.R + c3.G + c3.B) / 3;

                            int gg = (gray1 - gray2) * (gray1 - gray2) + (gray1 - gray3) * (gray1 - gray3);

                            int col = (int)(3 * Math.Sqrt(gg));

                            col = col < 0 ? 0 : col;
                            col = col > 255 ? 255 : col;

                            #region //彩色

                            //int rr = (c1.R - c2.R) * (c1.R - c2.R) + (c1.R - c3.R) * (c1.R - c3.R);
                            //int  gg = (c1.G - c2.G) * (c1.G - c2.G) + (c1.G - c3.G) * (c1.G - c3.G);
                            //int  bb = (c1.B - c2.B) * (c1.B - c2.B) + (c1.B - c3.B) * (c1.B - c3.B);

                            //r = (int)(3 * Math.Sqrt(rr));
                            //g = (int)(3 * Math.Sqrt(gg));
                            //b = (int)(3 * Math.Sqrt(bb));

                            //r = r < 0 ? 0 : r;
                            //r = r > 255 ? 255 : r;
                            //g= g < 0 ? 0 : g;
                            //g = g > 255 ? 255 : g; 
                            //b = b < 0 ? 0 : b;
                            //b = b > 255 ? 255 : b;
                            //tempColors[x + y * width] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);
                            #endregion
                            col = 255 - col;
                            target[x + y * width] = Color.FromArgb(255, (byte)col, (byte)col, (byte)col);

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion


        #region 图像曝光效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] ExposureEffect(Color[] source, int width, int height)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            int index = x + y * width;
                            Color c = source[index];

                            c.R = c.R < (byte)128 ? (byte)(255 - c.R) : c.R;
                            c.G = c.G < (byte)128 ? (byte)(255 - c.G) : c.G;
                            c.B = c.B < (byte)128 ? (byte)(255 - c.B) : c.B;

                            target[index] = c;

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion


        #region 图像染色效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] StaineEffect(Color[] source, int width, int height, Color staineColor)
        {


            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            int index = x + y * width;
                            Color c = source[index];

                            int gray = (c.R + c.G + c.B) / 3;

                            c.R = (byte)(Lerp(c.R, (gray * staineColor.R) / 255, 1));
                            c.G = (byte)(Lerp(c.G, (gray * staineColor.G) / 255, 1));
                            c.B = (byte)(Lerp(c.B, (gray * staineColor.B) / 255, 1));

                            target[index] = c;

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像浮雕效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] ReliefEffect(Color[] source, int width, int height, int depth)
        {

            int oriW = width;

            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            width = width - depth;
            height = height - depth;

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            int index = x + y * oriW;
                            int next = x + depth + (y + depth) * oriW;
                            Color c = source[index];
                            Color c1 = source[next];

                            int gray = (c.R + c.G + c.B) / 3;

                            int g2 = (c1.R + c1.G + c1.B) / 3;

                            int col = gray - g2 + 128;

                            col = col > 255 ? 255 : col;
                            col = col < 0 ? 0 : col;


                            target[index] = Color.FromArgb(255, (byte)col, (byte)col, (byte)col);

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像锐化效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] SharpenEffect(Color[] source, int width, int height)
        {


            int oriW = width;
            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];
            int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
            width = width - 1;
            height = height - 1;

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 1;
            int h = 1;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            int r = 0, g = 0, b = 0;
                            int Index = 0;
                            Color pixel;
                            for (int col = -1; col <= 1; col++)
                            {
                                for (int rom = -1; rom <= 1; rom++)
                                {
                                    pixel = source[(x + rom) + (y + col) * oriW];
                                    r += pixel.R * Laplacian[Index];
                                    g += pixel.G * Laplacian[Index];
                                    b += pixel.B * Laplacian[Index];
                                    Index++;
                                }
                            }
                            r = r > 255 ? 255 : r;
                            r = r < 0 ? 0 : r;
                            g = g > 255 ? 255 : g;
                            g = g < 0 ? 0 : g;
                            b = b > 255 ? 255 : b;
                            b = b < 0 ? 0 : b;
                            target[(x - 1) + (y - 1) * oriW] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像马赛克效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] MosaicEffect(Color[] source, int width, int height, int size)
        {


            Color[] target = new Color[source.Length];


            for (int x = 0; x < width - size; x += size)
            {
                for (int y = 0; y < height - size; y += size)
                {
                    int nx = x + size > width - 1 ? width - 2 : x + size;
                    int ny = y + size > height - 1 ? height - 2 : y + size;



                    //int r = 0, g = 0, b = 0;
                    Color c = source[x + y * width];
                    for (int i = x; i < nx; i++)
                    {
                        for (int j = y; j < ny; j++)
                        {
                            //Color c = colors[i + j * width];

                            target[i + j * width] = c;
                        }
                    }


                }
            }



            return target;
        }

        private static void Mosaic(int sx, int sy, int ex, int ey, int size, int width, int height, Color[] source, Color[] target)
        {
            for (int x = sx; x < ex;)
            {
                for (int y = sy; y < ey;)
                {
                    if (x == 0)
                    {
                        int count = 1;
                    }

                    int nx = x + size > width - 1 ? width - 1 : x + size;
                    int ny = y + size > height - 1 ? height - 1 : y + size;

                    Color c = source[x + y * width];

                    for (int i = x; i < nx; i++)
                    {
                        for (int j = y; j < ny; j++)
                        {
                            target[i + j * width] = c;
                        }
                    }
                    y = y + size;

                }
                x = x + size;

            }
        }

        #endregion

        #region 图像波浪效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] WaveEffect(Color[] source, int width, int height, double degree, double horizontalScale, double verticalScale)
        {




            Color[] target = new Color[source.Length];


            int centerX = width / 2;
            int centerY = height / 2;

            double hox = horizontalScale / 100d * (double)width;
            double voy = verticalScale / 100d * (double)height;


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {


                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        int x0 = x - centerX;
                        int y0 = centerY - y;

                        double x1 = 0, y1 = 0;



                        if (hox == 0)
                        {
                            x1 = degree * Math.Sin(2 * Math.PI * y0) + x0;

                        }
                        else
                        {
                            x1 = degree * Math.Sin(2 * Math.PI * y0 / hox) + x0;

                        }

                        if (voy == 0)
                        {
                            y1 = degree * Math.Cos(2 * Math.PI * x0) + y0;

                        }
                        else
                        {
                            y1 = degree * Math.Cos(2 * Math.PI * x0 / voy) + y0;

                        }


                        x1 = x1 + centerX;
                        y1 = centerY - y1;

                        x1 = x1 < 0 ? 0 : x1;
                        x1 = x1 > width - 1 ? width - 1 : x1;

                        y1 = y1 < 0 ? 0 : y1;
                        y1 = y1 > height - 1 ? height - 1 : y1;

                        Color c = Function.BiLinear(x1, y1, source, width, height);
                        target[x + y * width] = c;

                    }
                }


            }).Select(temp => temp.AsTask()).ToArray());






            return target;
        }

        #endregion

        #region 图像波浪效果

        /// <summary>
        /// 图像波浪效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="degree"></param>
        /// <param name="xAmplitude">x轴波幅</param>
        /// <param name="yAmplitude">Y轴波幅</param>
        /// <returns></returns>
        public static Color[] WaveEffect(Color[] source, int width, int height, double xWaveLenght, double yWaveLenght, double xAmplitude, double yAmplitude)
        {




            Color[] target = new Color[source.Length];


            int centerX = width / 2;
            int centerY = height / 2;

            //double hox = xAmplitude / 100d * (double)width / 4;
            //double voy = yAmplitude / 100d * (double)height / 4;

            //double xwl = xWaveLenght / 100d * (double)width / 4;
            //double ywl = yWaveLenght / 100d * (double)height / 4;

            double hox = xAmplitude / 100d * (double)width;
            double voy = yAmplitude / 100d * (double)height;

            double xwl = xWaveLenght / 100d * (double)width;
            double ywl = yWaveLenght / 100d * (double)height;

            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {


                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        double nx = (double)y / xwl;
                        double ny = (double)x / ywl;

                        double fx = 0, fy = 0;

                        switch (1)
                        {
                            case 1:
                                fx = Math.Sin(nx);
                                fy = Math.Cos(ny);
                                break;
                            case 2:

                                fx = nx % 1;
                                fy = ny % 1;

                                break;
                            case 3:
                                break;
                        }

                        double ox = x + hox * fx;
                        double oy = y + voy * fy;

                        if (ox < 0 || ox > width - 1 || oy < 0 || oy > height - 1)
                            continue;

                        Color c = Function.BiLinear(ox, oy, source, width, height);
                        target[x + y * width] = c;

                    }
                }


            }).Select(temp => temp.AsTask()).ToArray());






            return target;
        }

        #endregion

        #region 图像水波效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="Center">水波中心</param>
        /// <param name="r">水波半径</param>
        /// <param name="waveLength">波纹数量</param>
        /// <param name="amplitude">波幅</param>
        /// <param name="phase">阶段</param>
        /// <returns></returns>
        public static Color[] WaveRippleEffect(Color[] source, int width, int height, Point Center, double r, double waveNumber, double amplitude, double phase)
        {


            if (waveNumber == 0)
            {
                return source;
            }

            Color[] target = new Color[source.Length];

            var waveLength = r / waveNumber;



            double pi = Math.PI;


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        double dx = x - Center.X;
                        double dy = y - Center.Y;

                        double distance2 = dx * dx + dy * dy;
                        if (distance2 < r * r)
                        {
                            double distance = Math.Sqrt(distance2);
                            double amount = amplitude * Math.Sin(distance / waveLength * 2 * pi - phase);
                            amount = amount * (r - distance) / r;
                            amount = amount * waveLength / (distance + 0.0001);

                            double new_x = x + dx * amount;
                            double new_y = y + dy * amount;

                            //target[x + y * width] = Function.BiLinear(new_x, new_y, source, width, height);

                            new_x = Math.Min(Math.Max(0, new_x), width - 1);
                            new_y = Math.Min(Math.Max(0, new_y), height - 1);

                            target[x + y * width] = source[(int)new_x + (int)new_y * width];

                        }
                        else
                        {
                            target[x + y * width] = source[x + y * width];

                        }



                    }
                }

            }).Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        #endregion

        #region 图像渐变映射效果

        /// <summary>
        /// 渐变映射效果
        /// 先将图片转换成黑白,利用灰度值作为索引,在映射表寻找对应的颜色
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] GradientMappingEffect(Color[] source, int width, int height, Color[] mappColors)
        {


            var gradientMapp = CreateGradinetMapp(mappColors);

            List<IAsyncAction> list = new List<IAsyncAction>();

            Color[] target = new Color[source.Length];

            int d = width % 300;

            int mw = width / 12;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= 12; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;
                int ey = mh;
                ex = ex > width - 2 ? width - 2 : ex;

                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    for (int x = sx; x < ex; x++)
                    {
                        for (int y = sy; y < ey; y++)
                        {
                            Color c = source[x + y * width];

                            int sum = (c.B * 269 + c.R * 587 + c.G * 144) / 1000;
                            c.R = (byte)sum;
                            c.G = (byte)sum;
                            c.B = (byte)sum;

                            Color v = gradientMapp[sum];

                            target[x + y * width] = v;

                        }
                    }

                }));



                w = mw * i;


            }

            Task.WaitAll(list.Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        public static Color[] CreateGradinetMapp(Color[] cs)
        {
            Color[] GradientMapp = new Color[256 * 1];

            var canvasGradientStop = new CanvasGradientStop[cs.Length];

            for (int i = 0; i < cs.Length; i++)
            {


                canvasGradientStop[i] = new CanvasGradientStop
                {
                    Color = cs[i],
                    Position = (float)i / (float)(cs.Length - 1)
                };
            }
            using (CanvasRenderTarget crt = new CanvasRenderTarget(new CanvasDevice(), 256, 1, 96f))
            {


                CanvasLinearGradientBrush linearBrush = new CanvasLinearGradientBrush(crt.Device, canvasGradientStop)
                {
                    StartPoint = new System.Numerics.Vector2(0, 0),

                    EndPoint = new System.Numerics.Vector2(256, 0),

                };
                using (var ds = crt.CreateDrawingSession())
                {
                    ds.FillRectangle(0, 0, 256, 1, linearBrush);
                }

                crt.GetPixelColors().CopyTo(GradientMapp, 0);

            }

            return GradientMapp;
        }

        #endregion


        #region 图像三角化效果

        /// <summary>
        /// 图像三角化效果
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] TriangulateEffect(Color[] source, int width, int height)
        {

            var pencil = PencilEffect(source, width, height, 10);
            var cache = new Color[source.Length];
            var triangulate = new Color[source.Length];




            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
             {

                 for (int x = sx; x < ex; x++)
                 {
                     for (int y = sy; y < ey; y++)
                     {



                         var item = pencil[x + y * width];

                         if (item.B < 240)
                         {
                             cache[x + y * width] = Color.FromArgb(255, 0, 0, 0);
                         }
                         else
                         {
                             cache[x + y * width] = Color.FromArgb(255, 255, 255, 255);

                         }



                     }
                 }

             }).Select(p => p.AsTask()).ToArray());


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
             {

                 for (int x = sx; x < ex; x++)
                 {

                     if (x == 0 || x > width - 2)
                         continue;

                     int csy = 0, cey = 0;
                     bool start = false;

                     for (int y = sy; y < ey; y++)
                     {

                         if (y == 0 || y > height - 2)
                             continue;

                         var item = cache[x + y * width];

                         if (item.A == 0)
                         {
                             item.B = 255;
                         }

                         var r = cache[x + 1 + y * width];
                         var b = cache[x + (y + 1) * width];

                         var rc = Math.Abs(item.B - r.B);
                         var bc = Math.Abs(item.B - b.B);



                         if (bc > 10 || bc > 10)
                         {
                             if (start == false)
                             {
                                 triangulate[x + y * width] = Color.FromArgb(255, 255, 255, 255);
                                 csy = y;
                                 start = true;
                             }
                             else
                             {
                                 triangulate[x + y * width] = Color.FromArgb(255, 255, 255, 255);

                                 cey = y;

                                 int scy = csy + (cey - csy) / 2;

                                 triangulate[x + scy * width] = Color.FromArgb(255, 0, 0, 0);


                                 start = false;
                             }

                         }
                         else
                         {
                             triangulate[x + y * width] = Color.FromArgb(255, 255, 255, 255);


                         }





                     }
                 }

             }).Select(p => p.AsTask()).ToArray());

            object o = new object();

            int count = 0;




            Task.WaitAll(MultiThreading(triangulate.Length, (sx, ex) =>
            {


                for (int i = sx; i < ex; i++)
                {
                    var item = triangulate[i];
                    if (item.B == 0 && item.A != 0)
                    {
                        lock (o)
                        {
                            count++;
                        }

                    }
                }


            }).Select(p => p.AsTask()).ToArray());



            int size = (int)Math.Round((double)(count / Math.Max(width, height)) / ((source.Length) / count));

            size = size <= 0 ? 1 : size;



            List<Point> listPoint = new List<Point>();


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    if (x == 0 || x >= width - 1)
                        continue;

                    for (int y = sy; y < ey; y++)
                    {
                        if (y == 0 || y >= height - 1)
                            continue;
                        var item = triangulate[x + y * width];

                        if (item.B == 0 && item.A != 0)
                        {
                            lock (listPoint)
                            {
                                listPoint.Add(new Point(x, y));

                            }

                        }

                        y += size;
                    }
                    x += size;
                }

            }).Select(p => p.AsTask()).ToArray());







            for (double i = 0; i <= 1; i += 0.1)
            {
                //上边
                listPoint.Add(new Point((double)(width - 1) * i, 0));

                //下边
                listPoint.Add(new Point((double)(width - 1) * i, height - 1));

                listPoint.Add(new Point((double)(width - 1), (double)(height - 1) * i));
                listPoint.Add(new Point(0, (double)(height - 1) * i));

            }


            var lt = Delaunay.Delaunay1(listPoint);



            CanvasBitmap bitmap = CanvasBitmap.CreateFromColors(new CanvasDevice(), source, width, height);
            CanvasRenderTarget crt = new CanvasRenderTarget(bitmap.Device, bitmap.SizeInPixels.Width, bitmap.SizeInPixels.Height, 96f);
            using (var ds = crt.CreateDrawingSession())
            {


                ds.DrawImage(bitmap);


                Task.WaitAll(MultiThreading(lt.Count, (sx, ex) =>
                {


                    for (int i = sx; i < ex; i++)
                    {


                        lock (lt)
                        {
                            Triangle item = lt[i];


                            CanvasPathBuilder path = new CanvasPathBuilder(bitmap.Device);
                            path.BeginFigure(item.Side[0].P0.ToVector2());

                            Point p0 = item.Side[0].P0;
                            Point p1 = item.Side[1].P0;
                            Point p2 = item.Side[2].P0;

                            double x = (p0.X + p1.X + p2.X) / 3;
                            double y = (p0.Y + p1.Y + p2.Y) / 3;

                            Color c = source[(int)x + (int)y * width];
                            path.AddLine(item.Side[1].P0.ToVector2());
                            path.AddLine(item.Side[2].P0.ToVector2());
                            path.AddLine(item.Side[0].P0.ToVector2());

                            path.EndFigure(CanvasFigureLoop.Closed);
                            CanvasGeometry tr = CanvasGeometry.CreatePath(path);
                            ds.FillGeometry(tr, c);
                        }
                    }


                }).Select(p => p.AsTask()).ToArray());











            }

            var target = crt.GetPixelColors();


            return target;
        }



        #endregion


        #region 图像置换效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] ReplacementEffect(Color[] source, Color[] displacement, int width, int height, int disWidth, int disHeight, double horScale, double verScale, bool isStretch, bool isRepeat)
        {




            Color[] target = new Color[source.Length];

            double horizontalOffset = horScale / 100d * 128d;
            double verticalOffset = verScale / 100d * 128d;

            Color[] repColors = new Color[source.Length];
            CanvasBitmap bitmap = CanvasBitmap.CreateFromColors(new CanvasDevice(), displacement, disWidth, disHeight, 96f);
            CanvasRenderTarget crt = new CanvasRenderTarget(bitmap.Device, (float)width, (float)height, 96f);






            using (var ds = crt.CreateDrawingSession())
            {
                ds.Clear(Colors.Red);

                if (isStretch)
                {
                    float sx = (float)width / (float)disWidth;
                    float sy = (float)height / (float)disHeight;
                    Transform2DEffect scale = new Transform2DEffect();
                    scale.Source = bitmap;
                    scale.TransformMatrix = System.Numerics.Matrix3x2.CreateScale(sx, sy);

                    ds.DrawImage(scale);
                }
                else
                {
                    BorderEffect be = new BorderEffect()
                    {
                        Source = bitmap,
                        CacheOutput = true,
                    };

                    ds.DrawImage(be);
                }

            }






            repColors = crt.GetPixelColors();


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {


                    for (int y = sy; y < ey; y++)
                    {


                        int index = x + y * width;
                        Color jisuanC = repColors[index];


                        double ox = (jisuanC.R - 128d) / 128d * verticalOffset;
                        double oy = (jisuanC.G - 128d) / 128d * verticalOffset;

                        int cx = x + (int)ox;
                        int cy = y + (int)oy;

                        if (isRepeat)
                        {
                            cx = Math.Min(Math.Max(0, cx), width - 1);
                            cy = Math.Min(Math.Max(0, cy), height - 1);
                        }
                        else
                        {
                            cx = cx < 0 ? width + cx : cx;
                            cx = cx > width - 1 ? cx - (width - 1) : cx;

                            cy = cy < 0 ? height + cy : cy;
                            cy = cy > height - 1 ? cy - (height - 1) : cy;

                        }


                        int cxy = cx + cy * width;

                        target[index] = source[cxy];
                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }

        #endregion

        #region 图像置换效果

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Color[] EdgeWobblingEffect(Color[] source, Color[] displacement, int width, int height, int disWidth, int disHeight, double horScale, double verScale, bool isStretch, bool isRepeat)
        {


            var target = new Color[source.Length];


            int size = width * height;
            float strengthx = width / 3.5f;
            float strengthy = height / 3.5f;

            float strenght = Math.Max(strengthx, strengthy);



            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {


                    for (int y = sy; y < ey; y++)
                    {
                        int index = x + y * width;



                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }

        #endregion

        #region 图像亮度效果






        /// <summary>
        /// 图像亮度效果
        /// </summary>
        /// <param name="source">原颜色列表</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="brightness">亮度</param>
        /// <returns></returns>
        public static Color[] BrightnessEffect(Color[] source, int width, int height, double brightness)
        {

            brightness += 1;
            var target = new Color[source.Length];


            int size = width * height;
            float strengthx = width / 3.5f;
            float strengthy = height / 3.5f;

            float strenght = Math.Max(strengthx, strengthy);

            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {

                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        Color c = source[x + y * width];
                        var r = Math.Min(255, Math.Max(0, c.R * brightness));
                        var g = Math.Min(255, Math.Max(0, c.G * brightness));
                        var b = Math.Min(255, Math.Max(0, c.B * brightness));

                        target[x + y * width] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }



        #endregion


        #region 图像饱和度效果

        /// <summary>
        /// 饱和度效果
        /// </summary>
        /// <param name="source">原颜色列表</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="brightness">饱和度</param>
        /// <returns></returns>
        public static Color[] SaturationEffect(Color[] source, int width, int height, double saturation)
        {

            saturation += 1;
            var target = new Color[source.Length];


            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        Color c = source[x + y * width];


                        //计算灰度
                        var gray = (float)(c.R * 0.2125 + c.G * 0.7154 + c.B * 0.0721);
                        var cg = new Vector3(gray, gray, gray);
                        var cc = new Vector3(c.R, c.G, c.B);

                        var fc = Vector3.Lerp(cg, cc, (float)saturation);

                        var r = Math.Max(0, Math.Min(255, gray + (c.R - gray) * saturation));
                        var g = Math.Max(0, Math.Min(255, gray + (c.G - gray) * saturation));
                        var b = Math.Max(0, Math.Min(255, gray + (c.B - gray) * saturation));
                        target[x + y * width] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }



        #endregion


        #region 图像对比度效果

        /// <summary>
        /// 饱和度效果
        /// </summary>
        /// <param name="source">原颜色列表</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="brightness">饱和度</param>
        /// <returns></returns>
        public static Color[] ContrastEffect(Color[] source, int width, int height, double Contrast)
        {

            Contrast += 1;
            var target = new Color[source.Length];

            int size = width * height;
            float strengthx = width / 3.5f;
            float strengthy = height / 3.5f;
            float strenght = Math.Max(strengthx, strengthy);
            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        Color c = source[x + y * width];

                        //计算灰度
                        var gray = 0.5;
                        var r = c.R + (c.R - gray) * Contrast;
                        var g = c.G + (c.G - gray) * Contrast;
                        var b = c.B + (c.B - gray) * Contrast;
                        target[x + y * width] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);

                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }



        #endregion


        #region 扩散效果

        /// <summary>
        /// 扩散效果
        /// </summary>
        /// <param name="source">原颜色列表</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="luminanceThresholder">亮度</param>
        /// <returns></returns>
        public static Color[] BloomEffect(Color[] source, int width, int height, double luminanceThresholder, double blurSize, int gaussinNumber)
        {
            //先变量 再模糊，再相加

            var target = new Color[source.Length];


            var luminanColors = new Color[source.Length];
            //计算图片亮度
            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        var index = x + y * width;
                        Color c = source[index];
                        var val = Math.Clamp(luminance(c) / 255 - luminanceThresholder, 0, 1);
                        var r = c.R * val;
                        var g = c.G * val;
                        var b = c.B * val;
                        luminanColors[index] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);
                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            //return luminanColors;

            var gaussianColors = new Color[source.Length];

            luminanColors.CopyTo(gaussianColors, 0);



            for (int i = 0; i < gaussinNumber; i++)
            {
                var temp = Win2dGaussianBlurEffect(gaussianColors, width, height, (float)blurSize);
                temp.CopyTo(gaussianColors, 0);

                //gaussianColors = (Color[]) temp.Clone();
            }

            //return gaussianColors;

            //相加
            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        var index = x + y * width;
                        Color c = source[index];
                        Color c1 = gaussianColors[index];

                        var r = Math.Max(0, Math.Min(255, c.R + c1.R));
                        var g = Math.Max(0, Math.Min(255, c.G + c1.G));
                        var b = Math.Max(0, Math.Min(255, c.B + c1.B));

                        target[index] = Color.FromArgb(255, (byte)r, (byte)g, (byte)b);
                    }
                }

            }).Select(p => p.AsTask()).ToArray());

            return target;
        }

        /// <summary>
        /// 获取颜色亮度
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        private static double luminance(Color color)
        {
            return 0.2125 * color.R + 0.7154 * color.G + color.B * 0.0721;
        }

        #endregion

        #region //扩散效果

        /// <summary>
        /// 扩散效果
        /// </summary>
        /// <param name="source">原颜色列表</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="luminanceThresholder">亮度</param>
        /// <returns></returns>
        public static Color[] BrunEffect(Color[] source, int width, int height, double brunAmount, Color startColor, Color endColor)
        {


            var target = new Color[source.Length];

            var luminanColors = new Color[source.Length];
            Perlin per = new Perlin();

            double scale = 0.01;
            //计算图片亮度
            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {
                for (int x = sx; x < ex; x++)
                {
                    for (int y = sy; y < ey; y++)
                    {
                        var index = x + y * width;
                        Color c = source[index];
                        var noise = per.perlin(x * scale, y * scale);
                        if (noise < brunAmount)
                        {
                            luminanColors[index] = Color.FromArgb(0, 0, 0, 0);

                        }
                        else
                        {

                            var t = 1 - Smoothstep(0.0, 0.01, noise - brunAmount);
                            if (noise == 1)
                            {
                                t = 0;
                            }
                            var burnColor = LerpColor(startColor, endColor, t);
                            var finalColor = LerpColor(c, burnColor, t * Step(0.0001, brunAmount));

                            target[index] = finalColor;

                        }
                    }
                }

            }).Select(p => p.AsTask()).ToArray());








            return target;
        }

        private static double Smoothstep(double a, double b, double x)
        {
            double t = Saturate((x - a) / (b - a));
            return t * t * (3.0 - (2.0 * t));
        }

        private static double Saturate(double x)
        {
            return Math.Max(0, Math.Min(1, x));
        }

        private static double Step(double a, double x)
        {
            if (x < a)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }

        private static double Lerp(double a, double b, double t)
        {
            var v = a + (b - a) * t;
            return v;
        }

        private static Color LerpColor(Color form, Color to, double t)
        {
            var r = form.R + (to.R - form.R) * t;
            var g = form.G + (to.G - form.G) * t;
            var b = form.B + (to.B - form.B) * t;
            var a = form.A + (to.A - form.A) * t;
            return Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b);
        }

        private static double LerpDouble(double form, double to, double t)
        {
            return form + (to - form) * t;
        }

        #endregion
        /// <summary>
        /// 分成云彩
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="speed"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <param name="dz"></param>
        /// <returns></returns>
        public static Color[] LayeredCloudsEffect(int width, int height, double speed = 0.01, double dx = 0, double dy = 0, double dz = 0)
        {
            Color[] target = new Color[width * height];

            Perlin p = new Perlin();

            Task.WaitAll(MultiThreading(width, height, (sx, sy, ex, ey) =>
            {




                for (int y = sy; y < ey; y++)
                {


                    for (int x = sx; x < ex; x++)
                    {
                        double nosieValue = p.perlin(dx + x * speed, dy + y * speed, dz);



                        byte gray = (byte)(nosieValue * 255);
                        //gray = (byte)Math.Min(Math.Max((int)gray, 50), 150);
                        target[x + y * width] = Color.FromArgb(255, gray, gray, gray);
                    }
                }
            }, 20).Select(temp => temp.AsTask()).ToArray());


            return target;
        }

        public static Color[] Win2dGaussianBlurEffect(Color[] source, int width, int height, float blurAmount)
        {
            var target = new Color[source.Length];
            CanvasBitmap bitmap = CanvasBitmap.CreateFromColors(new CanvasDevice(), source, width, height);

            CanvasRenderTarget crt = new CanvasRenderTarget(bitmap.Device, bitmap.SizeInPixels.Width, bitmap.SizeInPixels.Height, 96f);

            using (var ds = crt.CreateDrawingSession())
            {


                GaussianBlurEffect gbe = new GaussianBlurEffect()
                {
                    Source = bitmap,
                    BlurAmount = blurAmount
                };

                ds.DrawImage(gbe);


            }

            target = crt.GetPixelColors();

            return target;

        }


        public static List<IAsyncAction> MultiThreading(int width, int height, Action<int, int, int, int> action, int threadLength = 12)
        {
            List<IAsyncAction> list = new List<IAsyncAction>();



            int d = width % 300;

            int mw = width / threadLength;
            int mh = height - 1;

            int w = 0;
            int h = 0;

            for (int i = 1; i <= threadLength; i++)
            {

                int sx = w;
                int sy = h;

                int ex = mw * i;

                if (i == threadLength)
                {
                    ex = width - 1;
                }
                int ey = mh;



                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    action.Invoke(sx, sy, ex, ey);
                }));



                w = mw * i;


            }

            return list;
        }

        public static List<IAsyncAction> MultiThreading(int lenght, Action<int, int> action, int threadLength = 12)
        {
            List<IAsyncAction> list = new List<IAsyncAction>();




            int mw = lenght / threadLength;


            int w = 0;


            for (int i = 1; i <= threadLength; i++)
            {

                int sx = w;

                int ex = mw * i;

                if (i == threadLength)
                {
                    ex = lenght - 1;
                }


                list.Add(Windows.System.Threading.ThreadPool.RunAsync(p =>
                {
                    action.Invoke(sx, ex);
                }));



                w = mw * i;


            }

            return list;
        }


    }
}
